 #include "cilent.h"
bool is_valid_command(CommandType cmd, const char* param, int num_params) {
    switch(cmd) {
    case CD:
    case MKDIR:
    case RMDIR:
    case REMOVE:
        // 这些命令最多只能有一个参数
        return (num_params <= 1);
    case PUTS:
    case GETS:
        // 这些命令可以有多个参数
        return true;
    case PWD:
    case LS:
    case QUIT:
        // 这些命令不能有参数
        return (num_params == 0);
    case LOGIN:
    case REGISTER:
        // 登录/注册命令需要两个参数
        return (num_params == 2);
    default:
        return false;
    }                                                                        
}
// 解析命令
int parse_command(char* input, Train* ptrain) {
    char cmd[16] = {0};
    char param[1024] = {0};
    char param_backup[1024] = {0}; // 参数备份
    int num_params = 0;

    // 分割命令和参数
    char *token = strtok(input, " ");
    if (token) {
        // 复制命令
        strncpy(cmd, token, sizeof(cmd)-1);
        cmd[sizeof(cmd)-1] = '\0';

        // 获取剩余部分作为参数
        token = strtok(NULL,"");
        if (token) {
            // 备份原始参数（在修改前）
            strncpy(param_backup, token, sizeof(param_backup)-1);
            param_backup[sizeof(param_backup)-1] = '\0';
            // 复制到param用于计数
            strncpy(param, token, sizeof(param)-1);
            param[sizeof(param)-1] = '\0';

            // 计算参数个数（使用strtok方法）
            char *saveptr;
            char *arg_token = strtok_r(param, " ", &saveptr);
            while (arg_token) {
                num_params++;
                arg_token = strtok_r(NULL, " ", &saveptr);
            }

            // 使用备份的参数值
            strncpy(param, param_backup, sizeof(param)-1);
            param[sizeof(param)-1] = '\0';
        }
    }
 printf("命令: %s, 参数: %s, 参数个数: %d\n", cmd, param, num_params);
    // 识别命令类型
    if (strcmp(cmd, "cd") == 0) {
        ptrain->commend = CD;
    } else if (strcmp(cmd, "pwd") == 0) {
        ptrain->commend = PWD;
    } else if (strcmp(cmd, "ls") == 0) {
        ptrain->commend = LS;
    } else if (strcmp(cmd, "mkdir") == 0) {
        ptrain->commend = MKDIR;
    } else if (strcmp(cmd, "rmdir") == 0) {
        ptrain->commend = RMDIR;
    } else if (strcmp(cmd, "puts") == 0) {
        ptrain->commend = PUTS;
    } else if (strcmp(cmd, "gets") == 0) {
        ptrain->commend = GETS;
    } else if (strcmp(cmd, "rm") == 0) {
        ptrain->commend = REMOVE;
    } else if (strcmp(cmd, "quit") == 0) {
        ptrain->commend = QUIT;
    } else if (strcmp(cmd, "login") == 0) {
        ptrain->commend = LOGIN;
    } else if (strcmp(cmd, "register") == 0) {
        ptrain->commend = REGISTER;
    }else {
        ptrain->commend = ERROR_COMMAND;
    }

    // 拷贝参数
    ptrain->length = strlen(param);
    if (ptrain->length > 0) {
        memcpy(ptrain->data, param, ptrain->length);
    }

    // 验证命令格式
    if (!is_valid_command(ptrain->commend, param, num_params)){
        ptrain->commend = ERROR_COMMAND;
        printf("错误：无效的命令格式\n");
        printf("正确格式示例：\n");
        printf("cd dirname    (最多一个参数)\n");
        printf("ls            (不能有参数)\n");
        printf("mkdir dirname (最多一个参数)\n");
        printf("puts text     (可以有多个参数)\n");
        printf("login username password (需要两个参数)\n");
        printf("register username password (需要两个参数)\n");
        return -1; // 返回错误
    }
    return 0;
}
// 认证操作（登录/注册）
int auth_action(int sockfd, CommandType action_type, const char* username, const char* password) {
    Train request, response;
    
    // 构造协议包
    memset(&request, 0, sizeof(request));
    request.commend = action_type;
    
    // [用户名长度(1B)][用户名][密码长度(1B)][密码]
    uint8_t user_len = (uint8_t)strlen(username);
    uint8_t pass_len = (uint8_t)strlen(password);
    
    request.data[0] = user_len;
    memcpy(request.data + 1, username, user_len);
    request.data[1 + user_len] = pass_len;
    memcpy(request.data + 2 + user_len, password, pass_len);
    
    request.length = 2 + user_len + pass_len;  // 总数据长度

    // 发送认证请求
    ssize_t sent = send(sockfd, &request, 
                       sizeof(request.commend) + sizeof(request.length) + request.length, 
                       0);
    if (sent <= 0) {
        perror("发送失败");
        return -1;
    }

    // 接收服务器响应
    ssize_t recvd = recv(sockfd, &response.commend, sizeof(response.commend), 0);
    recv(sockfd, &response.length, sizeof(response.length), 0);
    recv(sockfd, response.data, response.length, 0);

    if (recvd <= 0) {
        perror("服务器无响应");
        return -1;
    }

    // 处理响应结果
    switch (response.commend) {
        case LOGIN_SUCCESS:
            printf("\033[32m登录成功! 欢迎, %s\033[0m\n", username);
            return 0;
            
        case LOGIN_FAIL:
            printf("\033[31m登录失败: %.*s\033[0m\n", response.length, response.data);
            return -1;
            
        case REGISTER_SUCCESS:
            printf("\033[32m注册成功! 欢迎, %s\033[0m\n", username);
            return 0;
            
        case REGISTER_FAIL:
            printf("\033[31m注册失败: %.*s\033[0m\n", response.length, response.data);
            return -1;
            
        default:
            printf("\033[33m服务器返回未知响应: %d\033[0m\n", response.commend);
            return -1;
    }
}
